home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
program
/
cgazv3n4.zip
/
HELP-DIR.ZIP
/
HELP.C
next >
Wrap
C/C++ Source or Header
|
1989-07-13
|
8KB
|
286 lines
/********************** HELP.C *********************************
* Author: David Michmerhuizen
*
* Function: Provide pop-up help screens
*
* Compilers: Turbo C V1.5
*
* Memory models: all
*
* Usage:
* #include <help.h>
*
* ... your code ...
*
* ... when help is desired, call help() ...
*
* help(screen_numb);
*
* ... where 'screen_numb' is a screen number
* defined in help.h.
*
***************************************************************/
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAXLINKS 20 /* maximum links in 1 scrn */
#define LINKCHAR '|' /* link delimiter character */
typedef struct helplink_ {
int x,y;
char *name;
}
HELPLINK;
typedef struct helpscreen_ {
char *name;
long pos;
int len;
}
HELPSCREEN;
/* files from makehelp.exe */
#include "help.h" /* #defined screen numbers */
#include "helpstru.h" /* screen xref structure */
/* machine specific I/O routines (Turbo C 1.5, 2.x) */
/* (getkey returns extended scan codes in the leftmost 8 bits of a word) */
#define GETKEY(i) ( ((i) = getch()) ? (i) : ((i) |= (getch() << 8)))
#define DOWN_ARROW 20480
#define UP_ARROW 18432
#define LEFT_ARROW 19200
#define RIGHT_ARROW 19712
#define RETURN 13
#define ESCAPE 27
#define SET_INTENSE() textattr( (BLACK << 4) | WHITE)
#define SET_NORMAL() textattr( (BLACK << 4) | LIGHTGRAY)
#define SET_REVERSE() textattr( (LIGHTGRAY << 4) | BLACK)
#define CLS() clrscr()
#define DISP_CHAR(c) putch(c)
#define GOTOYX(y,x) gotoxy(x,y);
#define WHEREYX(y,x) { x = wherex(); y = wherey(); }
#define INVERT(s) { SET_REVERSE(); cputs( s); SET_NORMAL(); }
#define REVERT(s) { SET_INTENSE(); cputs( s); SET_NORMAL(); }
#define SAVE_SCREEN( y, x) { WHEREYX(svy, svx); gettext( 1, 1, x, y, sbuff);}
#define REST_SCREEN( y, x) { puttext( 1, 1, x, y, sbuff); GOTOYX( svy, svx);}
#define SCREEN_SIZE( y, x) { struct text_info ti; gettextinfo( &ti); \
y = ti.screenheight; x = ti.screenwidth; }
void help( unsigned int helpitem)
{
char *helpbuff = NULL;
char *sbuff = NULL;
FILE *helpfile = NULL;
int svx, svy;
char *c;
HELPLINK helplinks[ MAXLINKS];
int i, item, newitem;
unsigned int key;
int linkactive = FALSE;
int linkcount;
int x,y;
unsigned int sizex, sizey, sizescr;
/* help item number out of range ? */
if ( helpitem >= HELPSCREENS)
{
putchar('\x07');
return;
}
SCREEN_SIZE( sizey, sizex);
sizescr = sizey * sizex;
if ( !(sbuff = malloc( sizescr * 2)))
{
putchar('\x07');
return;
}
if ( !(helpbuff = malloc( sizescr)))
{
free( sbuff);
putchar('\x07');
return;
}
if ( !(helpfile = fopen( "help.hlp", "rb")))
{
free( sbuff);
free( helpbuff);
putchar('\x07');
return;
}
SAVE_SCREEN( sizey, sizex);
for(;;) /* until user hits escape */
{
/* test for valid number */
if ( helpitem >= HELPSCREENS)
{
putchar('\x07');
REST_SCREEN( sizey, sizex);
free( sbuff); free( helpbuff); fclose( helpfile);
return;
}
/* go get screen from help data file */
if ( fseek( helpfile, helpscreens[helpitem].pos, SEEK_SET) == -1L)
{
putchar('\x07');
REST_SCREEN( sizey, sizex);
free( sbuff); free( helpbuff); fclose( helpfile);
return;
}
fread( helpbuff, 1,
MIN(helpscreens[helpitem].len, sizescr),
helpfile);
helpbuff[ helpscreens[ helpitem].len] = '\0';
/* display screen, building array of links */
SET_NORMAL();
CLS();
x = y = 1;
linkcount = 0;
for ( c = helpbuff; *c; c++)
{
if ( *c == '\n')
{
x = 1;
y++;
continue;
}
/* start or stop of link */
if ( *c == LINKCHAR)
{
if ( !linkactive)
{
helplinks[linkcount].x = x;
helplinks[linkcount].y = y;
helplinks[linkcount].name = c+1;
linkcount++;
SET_INTENSE();
}
else
{
*c = '\0';
SET_NORMAL();
}
linkactive = !linkactive;
continue;
}
/* actually display characters (\xFF signals repeated character) */
i = (*c == '\xFF') ? (++c, *(c++)) : 1;
while(i--)
{
GOTOYX( y, x);
DISP_CHAR( *c);
x++;
}
}
/*
** screen is set up.
** now allow the user to cursor through the onscreen links,
** inverting the active link and allowing return
** to select the active link or esc to exit
*/
if ( !linkcount)
{
GETKEY( key);
REST_SCREEN( sizey, sizex);
free( sbuff); free( helpbuff); fclose( helpfile);
return;
}
newitem = item = 0;
GOTOYX( helplinks[item].y, helplinks[item].x);
INVERT( helplinks[item].name);
do
{
if ( newitem != item)
{
GOTOYX( helplinks[item].y, helplinks[item].x);
REVERT( helplinks[item].name);
GOTOYX( helplinks[newitem].y, helplinks[newitem].x);
INVERT( helplinks[newitem].name);
item = newitem;
}
GETKEY(key);
switch(key)
{
case DOWN_ARROW:
case RIGHT_ARROW:
if ( ++newitem >= linkcount)
newitem = 0;
break;
case UP_ARROW:
case LEFT_ARROW:
if ( --newitem < 0)
newitem = linkcount-1;
break;
case ESCAPE:
REST_SCREEN( sizey, sizex);
free( sbuff); free( helpbuff); fclose( helpfile);
return;
default:
break;
}
}
while ( key != RETURN);
/* user pressed return. look up link in link array */
for( i=0; i < HELPSCREENS; i++)
{
if ( !stricmp( helplinks[item].name, helpscreens[i].name))
break;
}
/* if link not found, do nothing. */
if ( i < HELPSCREENS)
helpitem = i;
}
} /* end of help */